Содержание
- Первоначальная настройка. Основы
- Распределение логирования по разным файлам
- Изменение дефолтного формата
- Автоматическое удаление логов
- Изменение уровня логирования
1. Первоначальная настройка. Основы
Установка зависимости
Импортируем модуль в главном файле (напр., main.py
) и определяем настройки логирования:
| from loguru import logger
logger.add("logs/application.log", format="{time} {level} {message}", level="DEBUG", retention = "1 day")
|
Директория logs
будет автоматически создана библиотекой loguru
, если не существует.
Прописываем логирование в main.py
, используя вместо print("Программа запущена"):
| logger.debug("Программа запущена")
|
Для добавления логирования в другие скрипты, просто дополнительно импортируем модуль:
another_script.py
| from loguru import logger
logger.debug("Запущен модуль another_script.py")
|
yet_one_script.py
| from loguru import logger
logger.debug("Запущен модуль yet_one_script.py")
|
В таком случае (когда мы не переопределяем настройки) логирование будет работать согласно параметрам, указанным в файле main.py
, то есть вся информация из всех скриптов будет записываться в logs/application.log
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | # main.py
from loguru import logger
from another_script import run_another_script
from yet_one_script import run_yet_one_script
logger.add("logs/application.log", format="{time} {level} {message}", level="DEBUG", retention = "1 day")
logger.debug("Программа запущена")
run_another_script()
run_yet_one_script()
# another_script.py
from loguru import logger
def run_another_script():
logger.debug("Запущен модуль another_script.py")
# yet_one_script.py
from loguru import logger
def run_yet_one_script():
logger.debug("Запущен модуль yet_one_script.py")
2024-01-20 16:14:46.322 | DEBUG | __main__:<module>:6 - Программа запущена
2024-01-20 16:14:46.323 | DEBUG | another_script:run_another_script:4 - Запущен модуль another_script.py
2024-01-20 16:14:46.323 | DEBUG | yet_one_script:run_yet_one_script:4 - Запущен модуль yet_one_script.py
|
2. Распределение логирования по разным файлам
Если же требуется писать логи каждого скрипта в самостоятельный файл, то настройки требуется переопределить.
Если мы будем добавлять настройки в каждый самостоятельный модуль, напр.:
| # yet_one_script.py
from loguru import logger
logger.add("logs/other.log", format="{time} {level} {message}", level="DEBUG", retention = "1 day")
def run_yet_one_script():
logger.debug("Запущен модуль yet_one_script.py")
|
То у нас просто появится много файлов под разными именами (logs/application.log
, logs/other.log
), которые будут дублировать друг друга. Далее показан пример, как можно разнести логи по разным файлам / прописать разные настройки:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | # main.py
from loguru import logger
from another_script import run_another_script
from yet_one_script import run_yet_one_script
logger.add("logs/application.log", filter=lambda record: record["extra"].get("name") == "application",enqueue=True,catch=True, format="{time} {level} {message}", level="DEBUG", retention = "1 day"
)
logger_app = logger.bind(name="application")
logger_app.debug("Программа запущена")
run_another_script()
run_yet_one_script()
# another_script.py
from loguru import logger
logger.add("logs/another_script.log", filter=lambda record: record["extra"].get("name") == "another_script", format="{time} {level} {message}", level="DEBUG", retention = "1 day")
logger_another = logger.bind(name="another_script")
def run_another_script():
logger_another.debug("Запущен модуль another_script.py")
# yet_one_script.py
from loguru import logger
logger.add("logs/yet_one_script.log", filter=lambda record: record["extra"].get("name") == "yet_one_script", format="{time} {level} {message}", level="DEBUG", retention = "1 day")
logger_yet = logger.bind(name="yet_one_script")
def run_yet_one_script():
logger_yet.debug("Запущен модуль yet_one_script.py")
|
В итоге появятся самостоятельные файлы для каждого скрипта, содержащие инфомацию только из этого скрипта:
├── logs
│ ├── another_script.log
│ ├── application.log
│ └── yet_one_script.log
3. Изменение дефолтного формата
Сбрасываем исходные настройки и прописываем своё форматирование через format
.
| logger.remove()
logger.add("logs/server.log",
format="<lvl>[</lvl><c>{time:DD.MM.YYYY HH:mm:ss.SSS}</c><lvl>]</lvl> <lvl>{message}</lvl>",
level="INFO"
)
|
В результате чего лог будет иметь следующий вид:
| [20.01.2024 00:01:02.967] Поиск файлов менее 3072 Кб
[20.01.2024 00:01:02.969] Удаление файла по размеру: '/home/dao2/Видео/rtsp_recorder/2024-01-20_00:00:47.mp4'
[20.01.2024 00:01:02.969] Размер: '1327' Kb
[20.01.2024 00:01:02.969] Причина: размер меньше '3072' Kb.
|
4. Автоматическое удаление логов
Применив следующий конфиг:
| logger.remove()
logger.add("logs/server.log",
format="<lvl>[</lvl><c>{time:DD.MM.YYYY HH:mm:ss.SSS}</c><lvl>]</lvl> <lvl>{message}</lvl>",
level="INFO",
retention="1 days",
rotation = "00:01",
compression="zip"
)
|
- логи будут храниться в файле
logs/server.log
- каждую ночь в 00:01 будет создаваться новый файл
server.log
, а предыдущая информация будет храниться в зазипованном файле (напр., server.2024-01-19_00-01-12_281803.log.zip
) и удалена через 1 день.
5. Изменение уровня логирования
Во время написания кода нам в любом случае потребуется добавлять логирование для анализа ошибок, данное логирование можно сохранять под уровнем DEBUG
. При написании нового скрипта или класса можно добавлять одну строку кода под уровнем INFO
, чтобы было общее представление, как работает программа без детального анализа кода.
Тем самым, закончив разработку, мы можем просто сменить уровень логирования с debug
на info
, лишив себя необходимости удаления излишнего логировния / мусора. А при анализе проблем в будущем можем переключиться снова на DEBUG
.
Важно:
-
логирование на уровне INFO
выводит сообщения, объявляемые на всех уровнях кроме debug
, а именно:
logger.critical
logger.error
logger.info
logger.success
logger.warning
-
логирование на уровне DEBUG
выводит абсолютно все сообщения (все уровни)
- остальные уровни (
CRITICAL
, ERROR
, SUCCESS
, WARNING
) выводят только себя и не показывают какой-либо другой уровень.
Итого, у нас есть проект:
├── another_script.py
├── config.py
├── main.py
└── yet_one_script.py
В config.py
мы прописываем используемый уровень логирования:
В main.py
прописываем проверку, что переменная log_level
равна одному из значений:
- CRITICAL
- DEBUG
- ERROR
- INFO
- SUCCESS
- WARNING
1
2
3
4
5
6
7
8
9
10
11
12 | try:
allowed_values = ["CRITICAL", "DEBUG", "ERROR", "INFO", "SUCCESS", "WARNING"]
if config.log_level.upper() not in allowed_values:
print('Файл config.py должен содержать переменную с одним из значений:')
print(f"{allowed_values}")
print('напр: log_level="INFO"')
exit()
except:
print('Файл config.py должен содержать переменную с одним из значений:')
print(f"{allowed_values}")
print('напр: log_level="INFO"')
exit()
|
Теперь, меняя значение переменной log_level="INFO"
, мы можем переключаться между уровнями логирования:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 | # config.py
log_level="INFO"
# main.py
from loguru import logger
import sys
from another_script import run_another_script
from yet_one_script import run_yet_one_script
import config
try:
allowed_values = ["CRITICAL", "DEBUG", "ERROR", "INFO", "SUCCESS", "WARNING"]
if config.log_level.upper() not in allowed_values:
print('Файл config.py должен содержать переменную с одним из значений:')
print(f"{allowed_values}")
print('напр: log_level="INFO"')
exit()
except:
print('Файл config.py должен содержать переменную с одним из значений:')
print(f"{allowed_values}")
print('напр: log_level="INFO"')
exit()
logger.remove()
logger.add(
"logs/application.log",
format="{time} {level} {message}",
retention = "1 day",
level=config.log_level.upper()
)
logger.error("Ошибок нет")
logger.warning("Сейчас запустится info-логирование")
logger.info("Логирование в config.py = INFO")
logger.debug("Логирование в config.py = DEBUG")
run_another_script()
logger.debug("Скрипт run_another_script отработал")
run_yet_one_script()
logger.debug("Скрипт run_yet_one_script отработал")
# another_script.py
from loguru import logger
def run_another_script():
logger.info("Запущен модуль another_script.py")
logger.debug("Запущен модуль another_script.py")
# yet_one_script.py
from loguru import logger
def run_yet_one_script():
logger.info("Запущен модуль yet_one_script.py")
logger.debug("Запущен модуль yet_one_script.py")
|
Выполнив данный код, в файле logs/application.log
отобразятся следующие строки:
| 2024-01-20T18:59:26.269211+0300 ERROR Ошибок нет
2024-01-20T18:59:26.269314+0300 WARNING Сейчас запустится info-логирование
2024-01-20T18:59:26.269346+0300 INFO Лоигрование в config.py = INFO
2024-01-20T18:59:26.269390+0300 INFO Запущен модуль another_script.py
2024-01-20T18:59:26.269426+0300 INFO Запущен модуль yet_one_script.py
|
Если же активировать уровень debug
, то лог изменится на:
| 2024-01-20T19:00:11.596537+0300 ERROR Ошибок нет
2024-01-20T19:00:11.596891+0300 WARNING Сейчас запустится info-логирование
2024-01-20T19:00:11.596989+0300 INFO Лоигрование в config.py = INFO
2024-01-20T19:00:11.597040+0300 DEBUG Лоигрование в config.py = DEBUG
2024-01-20T19:00:11.597097+0300 INFO Запущен модуль another_script.py
2024-01-20T19:00:11.597143+0300 DEBUG Запущен модуль another_script.py
2024-01-20T19:00:11.597186+0300 DEBUG Скрипт run_another_script отработал
2024-01-20T19:00:11.597233+0300 INFO Запущен модуль yet_one_script.py
2024-01-20T19:00:11.597296+0300 DEBUG Запущен модуль yet_one_script.py
2024-01-20T19:00:11.597336+0300 DEBUG Скрипт run_yet_one_script отработал
|
Можно также не писать в файл, а выводить лог в консоль:
| import sys
logger.add(
sys.stdout, # <= указываем вместо файла
format="{time} {level} {message}",
retention = "1 day",
level=config.log_level.upper()
)
|